<template>
  <view>
    <camera v-if="isPermission" device-position="back" style="width: 100%; height: 100vh; position: fixed" mode="scanCode" @scancode="scanProcess" :flash="flash" :initdone="(isInitDone = true)">
      <view @tap="back" class="backButton" :style="{ top: getStatusBarHeight, height: getCapsuleHeight, width: getCapsuleHeight }">
        <image src="../../static/back.png"></image>
      </view>
      <view class="cameraUI" v-if="isInitDone">
        <image class="scanBox" :src="isOnlyBarCode === true ? '../../static/BarCodeScan.png' : '../../static/scan.png'" mode="widthFix">
          <image class="scanEffect" src="../../static/scan-effect.png" mode="aspectFill"></image>
        </image>
        <view class="control">
          <view :class="['flashLight', { flashOpen: flash === 'on' }]" @tap="swithFlash" hover-class="flashClick">
            <image :src="flash === 'off' ? '../../static/flash_close.png' : '../../static/flash_open.png'"></image>
          </view>
        </view>
      </view>
    </camera>
  </view>
</template>

<script setup>
import { ref } from 'vue'
import { onShow } from '@dcloudio/uni-app'

const { isOnlyBarCode, scanResult } = defineProps({
  isOnlyBarCode: {
    type: Boolean,
    default: false
  },
  scanResult: {
    type: Function,
    default: (data) => {
      console.log(data)
      uni.showToast({
        icon: 'none',
        title: '扫描结果：' + data
      })
    }
  }
})

const SYSTEM_INFO = uni.getSystemInfoSync()
const getStatusBarHeight = SYSTEM_INFO.statusBarHeight + 5 + 'px'
const getCapsuleHeight = uni.getMenuButtonBoundingClientRect().height + 'px'

const isPermission = ref(false)
const isShowButtonAni = ref(false)
const isInitDone = ref(false)
const flash = ref('off')

onShow(() => {
  handleCameraPermission()
    .then(() => {
      isPermission.value = true
    })
    .catch((err) => {
      uni.showModal({
        title: '访问失败',
        content: '由于您' + err.message + '，无法使用本功能，如需使用请重新进入本页面进行授权。',
        showCancel: false,
        complete: (res) => {
          back()
        }
      })
    })
})

const back = () => {
  uni.navigateBack()
}

const swithFlash = () => {
  flash.value = flash.value === 'off' ? 'on' : 'off'
  uni.vibrateShort()
}

const scanProcess = (e) => {
  if (isOnlyBarCode === true && e.detail.type !== 'barcode') {
    uni.showToast({
      icon: 'error',
      title: '请扫描条形码'
    })
    uni.vibrateShort()
  } else {
    scanResult(e.detail.result)
    uni.vibrateLong()
  }
}

const handleCameraPermission = () => {
  return new Promise((resolve, reject) => {
    const showCameraPermissionModal = () => {
      uni.showModal({
        title: '提示',
        content: '检测到未授权摄像头权限，将无法使用本功能，是否前往设置权限？',
        success: (res) => {
          if (res.confirm) {
            uni.openSetting()
          } else {
            reject(new Error('未授权摄像头权限'))
          }
        }
      })
    }
    uni.getSetting({
      success: (res) => {
        const hasCameraPermission = res.authSetting.hasOwnProperty('scope.camera')
        if (hasCameraPermission) {
          if (!res.authSetting['scope.camera']) {
            showCameraPermissionModal()
          } else {
            resolve()
          }
        } else {
          uni.authorize({
            scope: 'scope.camera',
            success: () => {
              resolve()
            },
            fail: () => {
              showCameraPermissionModal()
            }
          })
        }
      },
      fail: (err) => {
        reject(err)
      }
    })
  })
}
</script>

<style lang="less" scoped>
.cameraUI {
  width: 750rpx;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  .scanBox {
    width: 636rpx;
    display: block;
    position: relative;
    .scanEffect {
      position: absolute;
      left: 50%;
      top: 5%;
      width: 595rpx;
      height: 86rpx;
      transform: translateX(-50%);
      z-index: 1;
      animation: scan 1.5s ease-in-out infinite;
    }
  }
  .BarCodeScanEffect {
    top: 30%;
    animation: BarCodeScan 1.5s ease-in-out infinite;
  }
  @keyframes scan {
    0% {
      top: 5%;
      opacity: 0;
    }

    20% {
      opacity: 1;
    }

    80% {
      opacity: 1;
    }

    100% {
      top: 70%;
      opacity: 0;
    }
  }
  .control {
    margin-top: 80rpx;
    height: 110rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    .flashLight {
      width: 90rpx;
      height: 90rpx;
      background: rgba(74, 74, 74, 0.8);
      box-shadow: rgba(142, 142, 142, 0.19) 0px 6px 15px 0px;
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      image {
        width: 60%;
        height: 60%;
      }
    }
    .flashOpen {
      backdrop-filter: blur(6px);
      background: rgba(255, 255, 255, 0.5);
    }
    .flashClick {
      transition: all 0.1s ease-in-out 0s;
      transform: scale(1.2);
    }
  }
}
.backButton {
  position: absolute;
  left: 30rpx;
  width: 65rpx;
  height: 65rpx;
  background: rgba(255, 255, 255, 0.5);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  image {
    width: 75%;
    height: 75%;
  }
}
</style>
